get_cmake_property(ENABLED_LANGUAGES ENABLED_LANGUAGES)
include(CheckCXXCompilerFlag)
include(CheckCCompilerFlag)

function(list_append var)
  foreach(arg ${ARGN})
    list(FIND ${var} ${arg} found)
    if(${found} EQUAL -1)
      list(APPEND ${var} ${arg})
    endif()
  endforeach()
  set(${var} ${${var}} PARENT_SCOPE)
endfunction()

macro(analyzer_flag)
  foreach(arg ${ARGN})
    string(REPLACE "+" "x" var ${arg})
    string(REGEX REPLACE "[^A-Za-z0-9_-]+" "-" var ${var})
    list(FIND ENABLED_LANGUAGES C found)
    if(${found} GREATER -1)
      check_c_compiler_flag(${arg} cx${var})
      if(cx${var})
        list_append(ANALYZER_CX ${arg})
      endif()
    endif()
    list(FIND ENABLED_LANGUAGES CXX found)
    if(${found} GREATER -1)
      check_cxx_compiler_flag(${arg} cx${var})
      if(cx${var})
        list_append(ANALYZER_CX ${arg})
      endif()
    endif()
  endforeach()
endmacro()

if(CMAKE_C_COMPILER_ID MATCHES "MSVC" OR CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
  # https://learn.microsoft.com/en-us/cpp/build/reference/analyze-code-analysis
  analyzer_flag(/analyze)
elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
  # https://gcc.gnu.org/onlinedocs/gcc-10.1.0/gcc/Static-Analyzer-Options.html
  analyzer_flag(-fanalyzer) # 10.1+
endif()

function(target_compile_analyzer)
  foreach(target ${ARGN})
    target_compile_options(${target} PRIVATE ${ANALYZER_CX})
  endforeach()
endfunction()
